package gov.pbc.nn.core.bdf.security;

import java.util.List;
import java.util.UUID;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.context.HttpRequestResponseHolder;
import org.springframework.stereotype.Component;

import com.bstek.bdf2.core.business.IUser;
import com.bstek.bdf2.core.context.ContextHolder;
import com.bstek.bdf2.core.security.SecurityInterceptorAdapter;
import com.bstek.bdf2.core.service.IDeptService;
import com.bstek.bdf2.core.service.IGroupService;
import com.bstek.bdf2.core.service.IPositionService;
import com.bstek.bdf2.core.service.IUserService;
import com.platform.application.sso.SSOClient;
import com.platform.application.sso.SSOUser;

import gov.pbc.nn.core.bdf.entity.User;
import gov.pbc.nn.core.bdf.service.UserService.DefaultUserRowMapper;
import gov.pbc.nn.core.dao.PbcnnCoreJdbcDao;

@Component
public class LoginInterceptorAdapter extends SecurityInterceptorAdapter {

	private static final String ssoKey = "u06db689120b94b31aa34b0f9a050e01c";

	@Resource(name = IUserService.BEAN_ID)
	private IUserService us;

	@Resource(name = IDeptService.BEAN_ID)
	private IDeptService ds;

	@Resource(name = IPositionService.BEAN_ID)
	private IPositionService ps;

	@Resource(name = IGroupService.BEAN_ID)
	private IGroupService gs;

	@Resource(name = PbcnnCoreJdbcDao.BEAN_ID)
	private PbcnnCoreJdbcDao jdbcDao;
	
	@Override
	public void beforeLogin(HttpRequestResponseHolder holder) {
	}

	@Override
	public void loginSuccess(HttpRequestResponseHolder holder) {
		String username = ContextHolder.getLoginUserName();
		User user = this.initUser(username);
		this.registerLoginInfo(user, holder);
	}

	@Override
	public void loginFailure(HttpRequestResponseHolder holder) {

	}

	@Override
	public void beforeAuthorization(HttpRequestResponseHolder holder) {
		if (ContextHolder.getLoginUser() == null) {
			// token 令牌（令牌只能使用一次，获取用户信息后令牌失效）
			String ticket = holder.getRequest().getParameter("ticket");
			if (StringUtils.isNotBlank(ticket)) {
				HttpServletRequest request = holder.getRequest();
				// 子系统的连接
				String linkUrl = request.getParameter("linkUrl");

				SSOClient sysClient = new SSOClient();

				// 获取登录 用户UID

				try {
					SSOUser ssoUser = sysClient.getSSOUser(ticket, linkUrl);
					String username = loadUsernameByFKsysname(ssoUser.getUserUid());// 用户uid
					
					String password = ssoUser.getPassword();// 密码
					String deptId = ssoUser.getDeptId();// 部门id
					String deptName = ssoUser.getDeptName();// 部门名称

					this.registerLoginInfo(this.initUser(username), holder);
				} catch (Exception e) {
					throw new SSOLoginException(e);
				}
			} else {
				String base64Username = holder.getRequest().getParameter(ssoKey);
				if (StringUtils.isNotBlank(base64Username)) {
					String username = StringUtils.substringAfter(new String(Base64.decodeBase64(base64Username)), ";");
					this.registerLoginInfo(this.initUser(username), holder);
				}
			}
		} else {
			String base64Username = holder.getRequest().getParameter(ssoKey);
			if (StringUtils.isNotBlank(base64Username)) {
				String username = StringUtils.substringAfter(new String(Base64.decodeBase64(base64Username)), ";");
				if (!StringUtils.equals(username, ContextHolder.getLoginUserName())) {
					this.registerLoginInfo(this.initUser(username), holder);
				}
			}
		}
	}

	@Override
	public void authorizationSuccess(HttpRequestResponseHolder holder) {
	}

	@Override
	public void authorizationFailure(HttpRequestResponseHolder holder) {
	}

	private User initUser(String username) {
		User user = (User) this.us.loadUserByUsername(username);
		// 为登录成功的用户设置所在部门、岗位及群组信息
		user.setDepts(ds.loadUserDepts(user.getUsername()));
		user.setPositions(ps.loadUserPositions(user.getUsername()));
		user.setGroups(gs.loadUserGroups(user.getUsername()));
		return user;
	}

	@Override
	protected void registerLoginInfo(IUser user, HttpRequestResponseHolder holder) {
		super.registerLoginInfo(user, holder);

		holder.getRequest().getSession().setAttribute("base64Username",
				Base64.encodeBase64String((UUID.randomUUID().toString() + ";" + user.getUsername()).getBytes()));
	}
	
	public String loadUsernameByFKsysname(String username) throws UsernameNotFoundException {
		String sql = "SELECT U.*,d.ID_,d.NAME_ FROM T_USER U LEFT JOIN bdf2_user_dept ud on u.USERNAME_=ud.USERNAME_ LEFT JOIN t_dept d on ud.DEPT_ID_=d.ID_ WHERE U.FK_SYS_NAME_=?";
		List<IUser> users = jdbcDao.getJdbcTemplate().query(sql, new Object[] { username }, new DefaultUserRowMapper());
		if (users.size() == 0) {
			throw new UsernameNotFoundException("User " + username + " is not exist");
		} else {
			User user = (User) users.get(0);
			
			return user.getUsername();
		}
	}
}
